#ifndef __LINUX_SPINLOCK_H
#define __LINUX_SPINLOCK_H
#include <asm-i386/system.h>

typedef struct {
    volatile unsigned int lock;
} spinlock_t;


typedef struct {
    spinlock_t lock;
} spinlock_cacheline_t;

#define spin_lock_string \
  "\n1:\t" \
  "lock ; decb %0\n\t" \
  "js 2f\n" \
  ".section .text.lock,\"ax\"\n" \
  "2:\t" \
  "cmpb $0,%0\n\t"\
  "rep;nop\n\t"\
  "jle 2b\n\t" \
  "jmp 1b\n" \
  ".previous"

static inline void spin_lock(spinlock_t *lock)
{
    __asm__ __volatile__(
    spin_lock_string
    :"=m" (lock->lock) : : "memory");
}

#define spin_unlock_string \
	"xchgb %b0, %1" \
		:"=q" (oldval), "=m" (lock->lock) \
		:"0" (oldval) : "memory"

static inline void spin_unlock(spinlock_t *lock)
{
    char oldval = 1;
    __asm__ __volatile__(
    spin_unlock_string
    );
}
#define local_irq_disable()	__cli()
#define local_irq_enable()	__sti()

#define spin_unlock_irqrestore(lock, flags)	do { spin_unlock(lock);  local_irq_restore(flags); } while (0)

#define spin_unlock_irq(lock)			do { spin_unlock(lock);  local_irq_enable();       } while (0)

#define spin_lock_irqsave(lock, flags)		do { local_irq_save(flags);       spin_lock(lock); } while (0)

#define spin_lock_irq(lock)			do { local_irq_disable();         spin_lock(lock); } while (0)

#define SPIN_LOCK_UNLOCKED (spinlock_t) { 1 }

#define spin_lock_init(x)	do { *(x) = SPIN_LOCK_UNLOCKED; } while(0)
#endif
